package com.mini.cn.goods.observer.ws;


import com.alibaba.fastjson.JSONArray;
import com.mini.cn.goods.common.PageQueryResult;
import com.mini.cn.goods.common.observes.IObserver;
import com.mini.cn.goods.common.observes.Message;
import com.mini.cn.goods.common.observes.YaKashMessageManager;
import com.mini.cn.goods.config.MessageConfig;
import com.mini.cn.goods.dao.DestDTO;
import com.mini.cn.goods.io.netty.ws.ParameterMap;
import com.mini.cn.goods.io.netty.ws.WebSocketSession;
import com.mini.cn.goods.io.netty.ws.info.PushMessage;
import com.mini.cn.goods.io.netty.ws.info.SessionUserInfo;
import com.mini.cn.goods.observer.message.ws.SocketOpenMessage;
import com.mini.cn.goods.po.OrderInfo;
import com.mini.cn.goods.po.UserModel;
import com.mini.cn.goods.po.dto.GroupGoods;
import com.mini.cn.goods.po.dto.OrderDto;
import com.mini.cn.goods.service.OrderService;
import com.mini.cn.goods.service.UserService;
import com.mini.cn.goods.servlet.ws.WSApplicationData;
import com.mini.cn.goods.servlet.ws.common.LCServiceConfig;
import com.mini.cn.goods.servlet.ws.common.PushHelper;
import com.mini.cn.goods.servlet.ws.common.ResponseMap;
import com.mini.cn.goods.servlet.ws.service.IPushResultCallback;
import com.mini.cn.goods.servlet.ws.service.IPushService;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.internal.util.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;

/**
 * Created with IntelliJ IDEA.
 * <p>
 * User: fly
 * Date: 2020-03-13
 * Time: 8:42 下午
 */
@Slf4j
@Service
public class SocketOpenHandle implements IObserver {

    @Autowired
    private IPushService pushService;
    @Autowired
    private IPushResultCallback pushResultHandle;

    @Autowired
    OrderService orderService;

    @Autowired
    UserService userService;

    @PostConstruct
    public void init() {
        YaKashMessageManager.INSTANCE.registerMessage(String.valueOf(MessageConfig.MessageType.SOCKETOPENSUCESS), this);
    }

    @Override
    public void onNoticeMessage(Message msgBody) {
        SocketOpenMessage openMessage = (SocketOpenMessage) msgBody;
        ParameterMap parameterMap = openMessage.parameterMap;
        WebSocketSession session = openMessage.session;
        try {
            //校验参数
            String userId = parameterMap.getParameter("userid");
            if (StringHelper.isBlank(userId)) {
                PushMessage myMsg = PushMessage.createDuplexPushMessage(LCServiceConfig.MsgSceneId.VERIFYHANDSHAKE,
                        LCServiceConfig.LCServiceCmd.VERIFYHANDSHAKE_TYPE,
                        new ResponseMap());
                //发送验证消息
                pushService.pushUserPushMessage(myMsg, session, pushResultHandle);
                session.close();
                return;
            }
            //注册并且发送注册消息
            registerUserAndSendVerifyMsg(userId, session);
        } catch (Exception e) {
            session.close();
        }
    }


    /**
     * 注册用户
     *
     * @param userId
     * @param session
     */
    private void registerUserAndSendVerifyMsg(String userId, WebSocketSession session) throws Exception {
        //先判断本地是否有重复
        WebSocketSession oldSession = WSApplicationData.INSTANCE.
                getUserSessionMap().get(userId);
        if (oldSession != null) {
            //删除注册消息缓存
            //把所有的注册都删除
            SessionUserInfo userInfo = oldSession.getAttribute(WebSocketSession.USERKEY);
            PushHelper.clearRegisterCache(oldSession, userInfo);
            oldSession.setAttribute(WebSocketSession.USERKEY, null);
            oldSession.close();
        }
        //存入客户端 初始化客户端的数据结构
        WSApplicationData.INSTANCE.
                getUserSessionMap().put(userId, session);
        SessionUserInfo userInfo = new SessionUserInfo();
        userInfo.setUserId(userId);
        String frontApp = userId.substring(userId.lastIndexOf("_") + 1);
        userInfo.setFrontApp(frontApp);
        userInfo.setWriteSeqId(new LongAdder());
        // userInfo.setRequestLog(new HashMap<>(200));
        userInfo.setRegisterMsgMap(new ConcurrentHashMap<>(1000));
        //设置初始心跳时间
        //userInfo.setLastPingTime(System.currentTimeMillis());
        session.setAttribute(WebSocketSession.USERKEY, userInfo);
        //自动注册 所有监听消息
        PushHelper.autoRegisterAllMsg(session, frontApp);
        //校验成功发送消息
        sendVerifyMsg(userId, session, frontApp);
    }


    //发送鉴权消息
    private void sendVerifyMsg(String userId, WebSocketSession session, String frontApp) throws Exception {
        ResponseMap map = new ResponseMap();
        PageQueryResult<DestDTO> pageQueryResult = orderService.findGroupOrderByTimeAndStatus(1, 1000, 1, 2);
        List<DestDTO> destDTOS = pageQueryResult.getQueryResult();
        List<OrderDto> orderDtos = new ArrayList<>();
        if (null != destDTOS && !destDTOS.isEmpty()) {
            for (DestDTO destDTO : destDTOS) {
                OrderInfo orderInfo = destDTO.getOrderinfo();
                byte pay = orderInfo.getcPayway();
                if ((byte) 2 == pay) {
                    OrderDto orderDto = new OrderDto();
                    String list = orderInfo.getcCoffeelist();
                    long ctime = orderInfo.getcCtime().getTime();
                    orderDto.setCTime(ctime);
                    List<GroupGoods> goods = JSONArray.parseArray(list, GroupGoods.class);
                    orderDto.setGoodsList(goods);
                    UserModel userModel = userService.findUserByOpenId(orderInfo.getcOpenid(), orderInfo.getcAppid());
                    orderDto.setUserName(userModel.userInfo.getcName());
                    orderDto.setUserLogo(userModel.userInfo.getcLogo());
                    orderDto.setAppId(orderInfo.getcAppid());
                    orderDtos.add(orderDto);
                }
            }
        }
        map.setData(orderDtos);
        //发送注册成功消息
        PushMessage myMsg = PushMessage.createDuplexPushMessage(String.format(LCServiceConfig.MsgSceneId.VERIFYHANDSHAKE, frontApp),
                LCServiceConfig.LCServiceCmd.VERIFYHANDSHAKE_TYPE,
                map);
        //发送验证消息
        pushService.pushUserPushMessage(myMsg, session, pushResultHandle);
    }

    @Override
    public String getObserverName() {
        return "我是连接建立成功以后的观察者";
    }

}
